﻿//----------------------------------------
// Program.cs (c) 2008 by Eduardo Ribeiro
//----------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using AgenteCMX;
using System.IO;
using System.Xml.Serialization;
using System.Reflection;
using Cmx.Agent.ROOT.CIMV2;
using System.Net.Mail;
using System.Net;
using System.Globalization;

namespace Cmx.Agent
{
    class Program
    {
        const int KB = 1024;
        const int MB = KB * KB;

        /// <summary>
        /// Criação de instancias para utilizar as classes Win32_ComputerSystem, Win32_Processor, Win332_LogicalDisk,
        /// Win32_OperatingSystem, Win32_Product.
        /// Utilização de Resources Strings (Por defeito en-EN, mas também temos pt-PT).
        /// </summary>
        public static void Main(string[] args)
        {
            ROOT.CIMV2.ComputerSystem _computerSystem = new ROOT.CIMV2.ComputerSystem(Environment.MachineName);
            ROOT.CIMV2.Processor.ProcessorCollection _processorCollection = ROOT.CIMV2.Processor.GetInstances();
            ROOT.CIMV2.LogicalDisk.LogicalDiskCollection _logicalDiskCollection = ROOT.CIMV2.LogicalDisk.GetInstances();
            ROOT.CIMV2.OperatingSystem _operatingSystem = new ROOT.CIMV2.OperatingSystem();
            ROOT.CIMV2.Product.ProductCollection _productCollection = ROOT.CIMV2.Product.GetInstances();

            /// Utilização da Management Class Win32_ComputerSystem.
            Console.WriteLine(Resources.Manufacturer + _computerSystem.Manufacturer);
            Console.WriteLine(Resources.Model + _computerSystem.Model);

            try
            {
                Console.WriteLine(Resources.PcSystemType + Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.PCSystemTypeValues), _computerSystem.PCSystemType));
            }
            catch (ManagementException) {}

            Console.WriteLine(Resources.NumberOfProcessors + (_computerSystem.NumberOfProcessors));

            try
            {
                Console.WriteLine(Resources.NumberOfLogicalProcessors + _computerSystem.NumberOfLogicalProcessors);
            }
            catch (ManagementException) { }

            Console.WriteLine(Resources.Memory + Convert.ToString(_computerSystem.TotalPhysicalMemory / MB) + Resources.Mb);
            Console.WriteLine(Resources.TimeZoneOffset + Convert.ToString(System.TimeSpan.FromMinutes(_computerSystem.CurrentTimeZone), CultureInfo.CurrentCulture));

            try
            {
                Console.WriteLine(Resources.ComputerName + _computerSystem.DNSHostName);
            }
            catch (ManagementException) { }

            if ((_computerSystem.PartOfDomain) == true)
            {
                Console.WriteLine(Resources.Domain + _computerSystem.Domain);
                Console.WriteLine(Resources.DomainRole + Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.DomainRoleValues), _computerSystem.DomainRole));
            }
            else
            {
                Console.WriteLine(Resources.Workgroup + _computerSystem.Workgroup);
            }

            Console.WriteLine(Resources.UserName + _computerSystem.UserName);
            Console.WriteLine(Resources.AdminPasswordStatus + Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.AdminPasswordStatusValues), _computerSystem.AdminPasswordStatus));

            /// Utilização da Management Class Win32_Processor.
            foreach (ROOT.CIMV2.Processor _processor in _processorCollection)
            {
                Console.WriteLine();
                Console.WriteLine(Resources.AddressWidth + Convert.ToString(_processor.AddressWidth) + Resources.Bit);
                Console.WriteLine(Resources.Architecture + Enum.GetName(typeof(ROOT.CIMV2.Processor.ArchitectureValues), _processor.Architecture));
                Console.WriteLine(Resources.Family + Enum.GetName(typeof(ROOT.CIMV2.Processor.FamilyValues), _processor.Family));
                Console.WriteLine(Resources.L2CacheSize + Convert.ToString(_processor.L2CacheSize / KB) + Resources.Mb);

                try
                {
                    Console.WriteLine(Resources.L3CacheSize + Convert.ToString(_processor.L3CacheSize / KB) + Resources.Mb);
                }
                catch (ManagementException) { }

                Console.WriteLine(Resources.Manufacturer + _processor.Manufacturer);

                try
                {
                    Console.WriteLine(Resources.NumberOfCores + _processor.NumberOfCores);
                }
                catch (ManagementException) { }

                try
                {
                    Console.WriteLine(Resources.NumberOfLogicalProcessors + _processor.NumberOfLogicalProcessors);
                }
                catch (ManagementException) { }

                Console.WriteLine(Resources.UpgradeMethod + Enum.GetName(typeof(ROOT.CIMV2.Processor.UpgradeMethodValues), _processor.UpgradeMethod));
            }

            /// Utilização da Management Class Win32_LogicalDisk.
            foreach (ROOT.CIMV2.LogicalDisk _logicalDisk in _logicalDiskCollection)
            {
                Console.WriteLine();
                Console.WriteLine(Resources.DiskName + _logicalDisk.Name);
                Console.WriteLine(Resources.FileSystem + _logicalDisk.FileSystem);
                Console.WriteLine(Resources.VolumeName + _logicalDisk.VolumeName);
                Console.WriteLine(Resources.DiskSize + Convert.ToString(_logicalDisk.Size / MB) + Resources.Mb);
                Console.WriteLine(Resources.FreeSpace + Convert.ToString(_logicalDisk.FreeSpace / MB) + Resources.Mb);
                Console.WriteLine(Resources.DriveType + Enum.GetName(typeof(ROOT.CIMV2.LogicalDisk.DriveTypeValues), _logicalDisk.DriveType));
                Console.WriteLine(Resources.MediaType + Enum.GetName(typeof(ROOT.CIMV2.LogicalDisk.MediaTypeValues), _logicalDisk.MediaType));
            }

            /// Utilização da Management Class Win32_OperatingSystem.
            Console.WriteLine();
            
            try
            {
                Console.WriteLine(Resources.Manufacturer + _operatingSystem.Manufacturer);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.Caption + _operatingSystem.Caption);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.OsArchitecture + _operatingSystem.OSArchitecture);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.CsdVersion + _operatingSystem.CSDVersion);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.SystemDrive + _operatingSystem.SystemDrive);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.FreePhysicalMemory + Convert.ToString(_operatingSystem.FreePhysicalMemory / KB) + Resources.Mb);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.FreeVirtualMemory + Convert.ToString(_operatingSystem.FreeVirtualMemory / KB) + Resources.Mb);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.CountryCode + _operatingSystem.CountryCode);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.OsLanguage + _operatingSystem.OSLanguage);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.LastBootUpTime + _operatingSystem.LastBootUpTime);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.LocalDataTime + _operatingSystem.LocalDateTime);
            }
            catch (ManagementException) { }

            try
            {
                Console.WriteLine(Resources.NumberOfUsers + _operatingSystem.NumberOfUsers);
            }
            catch (ManagementException) { }

            /// Utilização da Management Class Win32_Product.
            foreach (ROOT.CIMV2.Product _product in _productCollection)
            {
                Console.WriteLine();
                Console.WriteLine(Resources.Vendor + _product.Vendor);
                Console.WriteLine(Resources.Name + _product.Name);
                Console.WriteLine(Resources.Version + _product.Version);
                Console.WriteLine(Resources.InstallDate + _product.InstallDate);
                Console.WriteLine(Resources.InstallLocation + _product.InstallLocation);
                
                try
                {
                    Console.WriteLine(Resources.Language + _product.Language);
                }
                catch (ManagementException) { }
            }
            
            /// ComputerSystemTag.
            Computer computer = new Computer();
            computer.ComputerSystemTag = new ComputerSystemTag();

            computer.ComputerSystemTag.Manufacturer = _computerSystem.Manufacturer;
            computer.ComputerSystemTag.Model = _computerSystem.Model;

            try
            {
                computer.ComputerSystemTag.PcSystemType = Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.PCSystemTypeValues), _computerSystem.PCSystemType);
            }
            catch (ManagementException) { }
                
            computer.ComputerSystemTag.NumberOfProcessors = Convert.ToInt32(_computerSystem.NumberOfProcessors);
            
            try
            {
                computer.ComputerSystemTag.NumberOfLogicalProcessors = Convert.ToInt32(_computerSystem.NumberOfLogicalProcessors);
            }
            catch (ManagementException) { }
                
            computer.ComputerSystemTag.Memory = Convert.ToString((_computerSystem.TotalPhysicalMemory / MB) + Resources.Mb);
            computer.ComputerSystemTag.TimeZoneOffset = Convert.ToString(System.TimeSpan.FromMinutes(_computerSystem.CurrentTimeZone));
            
            try
            {
                computer.ComputerSystemTag.ComputerName = _computerSystem.DNSHostName;
            }
            catch (ManagementException) { }

            if ((_computerSystem.PartOfDomain) == true)
            {
                computer.ComputerSystemTag.Domain = _computerSystem.Domain;
                computer.ComputerSystemTag.DomainRole = Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.DomainRoleValues), _computerSystem.DomainRole);
            }
            else
            {
                computer.ComputerSystemTag.Workgroup = _computerSystem.Workgroup;
            }

            computer.ComputerSystemTag.UserName = _computerSystem.UserName;
            computer.ComputerSystemTag.AdminPasswordStatus = Enum.GetName(typeof(ROOT.CIMV2.ComputerSystem.AdminPasswordStatusValues), _computerSystem.AdminPasswordStatus);

            /// ProcessorTag.
            computer.ProcessorsTag = new ProcessorsTag();
            computer.ProcessorsTag.ProcessorTag = new ProcessorTag[_processorCollection.Count];

            int j = 0;

            foreach (ROOT.CIMV2.Processor _processor in _processorCollection)
            {
                ProcessorTag processorTag = new ProcessorTag();

                processorTag.AddressWidth = Convert.ToString((_processor.AddressWidth) + Resources.Bit);
                processorTag.Architecture = Enum.GetName(typeof(ROOT.CIMV2.Processor.ArchitectureValues), _processor.Architecture);
                processorTag.Family = Enum.GetName(typeof(ROOT.CIMV2.Processor.FamilyValues), _processor.Family);
                processorTag.L2CacheSize = Convert.ToString((_processor.L2CacheSize / KB) + Resources.Mb);

                try
                {
                    processorTag.L3CacheSize = Convert.ToString((_processor.L3CacheSize / KB) + Resources.Mb);
                }
                catch (ManagementException) { }

                processorTag.Manufacturer = _processor.Manufacturer;

                try
                {
                    processorTag.NumberOfCores = Convert.ToInt32(_processor.NumberOfCores);
                }
                catch (ManagementException) { }

                try
                {
                    processorTag.NumberOfLogicalProcessors = Convert.ToInt32(_processor.NumberOfLogicalProcessors);
                }
                catch (ManagementException) { }

                processorTag.UpgradeMethod = Enum.GetName(typeof(ROOT.CIMV2.Processor.UpgradeMethodValues), _processor.UpgradeMethod);

                computer.ProcessorsTag.ProcessorTag[j] = processorTag;
                j++;
            }
            
            /// LogicalDiskTag.
            /// Cria um novo objecto LogicalDisksTag no _computer (De iníco está a null -> Não ser pode usar).
            computer.LogicalDisksTag = new LogicalDisksTag();

            /// Indica que a propriedade LogicalDiskTag (Array) do _computer.LogicalDisksTag (Objecto criado em cima)
            /// contém o número de elemetos = a _logicalDiskCollection.
            computer.LogicalDisksTag.LogicalDiskTag = new LogicalDiskTag[_logicalDiskCollection.Count];

            /// Iterar para cada um dos elementos de _logicalDiskCollection
            j = 0;

            foreach (ROOT.CIMV2.LogicalDisk _logicalDisk in _logicalDiskCollection)
            {
                /// Para cada elemento de _logicalDiskCollection (que se chama _logicalDisk)...

                /// Crio um novo elemento do tipo LogicalDiskTag().
                LogicalDiskTag logicalDiskTag = new LogicalDiskTag();

                /// Carrego com os dados de _logicalDisk.
                logicalDiskTag.DiskName = _logicalDisk.Name;
                logicalDiskTag.FileSystem = _logicalDisk.FileSystem;
                logicalDiskTag.VolumeName = _logicalDisk.VolumeName;
                logicalDiskTag.DiskSize = Convert.ToString((_logicalDisk.Size / MB) + Resources.Mb);
                logicalDiskTag.FreeSpace = Convert.ToString((_logicalDisk.FreeSpace / MB) + Resources.Mb);
                logicalDiskTag.DriveType = Enum.GetName(typeof(ROOT.CIMV2.LogicalDisk.DriveTypeValues), _logicalDisk.DriveType);
                logicalDiskTag.MediaType = Enum.GetName(typeof(ROOT.CIMV2.LogicalDisk.MediaTypeValues), _logicalDisk.MediaType);

                /// O _computer.LogicalDisksTag.LogicalDiskTag na posição j fica com o logicalDiskTag criado em cima.
                computer.LogicalDisksTag.LogicalDiskTag[j] = logicalDiskTag;
                j++;
            }

            /// OperatingSystemTag.
            computer.OperatingSystemTag = new OperatingSystemTag();

            try
            {
                computer.OperatingSystemTag.Manufacturer = _operatingSystem.Manufacturer;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.Caption = _operatingSystem.Caption;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.OsArchitecture = _operatingSystem.OSArchitecture;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.CsdVersion = _operatingSystem.CSDVersion;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.SystemDrive = _operatingSystem.SystemDrive;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.FreePhysicalMemory = Convert.ToString((_operatingSystem.FreePhysicalMemory / KB) + Resources.Mb);
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.FreeVirtualMemory = Convert.ToString((_operatingSystem.FreeVirtualMemory / KB) + Resources.Mb);
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.CountryCode = _operatingSystem.CountryCode;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.OsLanguage = Convert.ToInt32(_operatingSystem.OSLanguage);
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.LastBootUpTime = _operatingSystem.LastBootUpTime;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.LocalDataTime = _operatingSystem.LocalDateTime;
            }
            catch (ManagementException) { }

            try
            {
                computer.OperatingSystemTag.NumberOfUsers = Convert.ToInt32(_operatingSystem.NumberOfUsers);
            }
            catch (ManagementException) { }

            /// ProductTag.
            computer.ProductsTag = new ProductsTag();
            computer.ProductsTag.ProductTag = new ProductTag[_productCollection.Count];

            j = 0;

            foreach (ROOT.CIMV2.Product _product in _productCollection)
            {
                ProductTag productTag = new ProductTag();

                productTag.Vendor = _product.Vendor;
                productTag.Name = _product.Name;
                productTag.Version = _product.Version;
                productTag.InstallDate = _product.InstallDate;
                productTag.InstallLocation = _product.InstallLocation;
                
                try
                {
                    productTag.Language = _product.Language;
                }
                catch (ManagementException) { }

                computer.ProductsTag.ProductTag[j] = productTag;
                j++;
            }
            

            /// Neste caso a localização do ficheiro XML gerado será onde vai ser executada a aplicação.
            Assembly location = Assembly.GetExecutingAssembly();
            string path = Path.GetDirectoryName(location.Location);
            path = Path.Combine(path, "Computer.xml");

            /// Neste caso a localização do ficheiro XML gerado será na diretoria onde escrevem todas as aplicações.
            // string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
            // path = Path.Combine(path, "SystemDescription.xml");

            /// Neste caso a localização do ficheiro XML gerado será na diretoria onde são colocados ficheiros temporários.
            // System.IO.GetTempFileName();

            TextWriter writer = new StreamWriter(path);
            
            try
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Computer));
                xmlSerializer.Serialize(writer, computer);
            }
            finally
            {
                writer.Dispose();
            }

            /// Verifica se o parametro é um endereço "mailFrom".
            string mailFrom = "default@default.com";

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].StartsWith("/mailfrom:", StringComparison.InvariantCultureIgnoreCase))
                {
                    mailFrom = args[i].Substring(10);
                }
            }
            
            /// Envio de email.
            SendEmail(path, mailFrom);

            Console.WriteLine();
            Console.WriteLine("----------------------------------------------------------------------------");
            Console.WriteLine("Ficheiro XML criado com o nome - Computer.xml - !!!");
            Console.WriteLine("----------------------------------------------------------------------------");
            Console.WriteLine();
            Console.WriteLine("Pressione em qualquer tecla para sair...");
            Console.ReadKey();
        }

        private static void SendEmail(string path, string mailFrom)
        {
            ///Criação da menssagem
            MailMessage mensagem = new MailMessage(mailFrom, "suportecmx@gmail.com");

            mensagem.Subject = "Dados sobre o computador";
            mensagem.Body = "Ficheiro XML gerado pelo AgentCMX sobre o computador.";
            mensagem.Attachments.Add(new Attachment(path));

            ///Introdução da configuração    
            SmtpClient client = new SmtpClient();
            
            client.Credentials = new NetworkCredential("suportecmx@gmail.com", "AgentCMX123");
            client.Port = 587;
            client.Host = "smtp.gmail.com";
            client.EnableSsl = true;
            
            try
            {
            client.Send(mensagem);
            }
            catch (SmtpException ex)
            {
                Console.WriteLine();
                Console.WriteLine(ex.Message);
            }
        }
    }
}